Best phrase I can think of is minimal.
While interfaces IMO have exceedingly more power than an extension ever will, abstracts are the perfect minimal implementation of an interface. If you have an interface with say a public function loadINI() method on it, and every class uses the same INI file, then it makes sense to use an abstract to provide this minimal implementation detail instead of having the exact method on every class implementing it. This is especially true if it makes use of a method that has unknown implementation at the time, allowing you're class to call this method; if there is no call to a required method, a concrete adapter may make more sense (an adapter provides non-implementation by throwing exceptions or providing no implementation details for the concrete class). You may also have a base class that does not implement a provided interface and still defines a method, and then later extend it and implement this method. That will also work, though the base is not itself considered a typeof the given interface.
Note that the above can be easily modified to create an unrecognized bug in PHP (as in, the PHP team threw out my bug report indicating normal behaviour) when it is not the case. If you use this class structure:
<?php
interface IInterface
{
public function test();
}
class Grandfather
{
private function __construct()
{
}
private function test()
{
printf("%s\n", __METHOD__);
}
}
class Father extends Grandfather implements IInterface
{
public function __construct()
{
printf("%s\n", __METHOD__);
}
public function test()
{
printf("%s\n", __METHOD__);
}
}
class Son extends Father
{
protected function __construct()
{
parent::__construct();
printf("%s\n", __METHOD__);
}
public static function createInstance()
{
return new self;
}
private function test()
{
parent::test();
printf("%s\n", __METHOD__);
}
}
?>
Grandfather must not implement the interface and declare the same method signature as private.
And attempt to use the test method on an instance of Son, it will succeed and throw an illegal access error. This is incorrect as the error should be thrown when the linking occurs for the Son to Father - a child cannot demote the access level of a parent. This bug chews on me so much.